core: Use mmap() with O_NOATIME if merely reading archive-z2 entries
authorColin Walters <walters@verbum.org>
Sun, 2 Dec 2012 20:20:17 +0000 (15:20 -0500)
committerColin Walters <walters@verbum.org>
Sun, 2 Dec 2012 20:20:17 +0000 (15:20 -0500)
Previously we'd open(path, O_NOATIME) and do a series of small read()
calls to just parse the header.  I think this will trigger kernel readahead
into the compressed portion, but we don't care about that.

This should be more efficient.

src/libgsystem
src/libostree/ostree-core.c

index c17376d4acbddfa1909d24167d3ce24531b3db1a..76d4b356378dc3549d402bfdd0bc953da7106f08 160000 (submodule)
@@ -1 +1 @@
-Subproject commit c17376d4acbddfa1909d24167d3ce24531b3db1a
+Subproject commit 76d4b356378dc3549d402bfdd0bc953da7106f08
index 3a8dc733d62cc436e1f9aa9aeffe774af8870443..8d40319bdc89d955f749624d2a83b2c302b2038c 100644 (file)
@@ -540,28 +540,45 @@ ostree_content_file_parse (gboolean                compressed,
   struct stat stbuf;
   ot_lobj GInputStream *file_input = NULL;
   ot_lobj GInputStream *ret_input = NULL;
-  ot_lobj GFileInfo *content_file_info = NULL;
   ot_lobj GFileInfo *ret_file_info = NULL;
   ot_lvariant GVariant *ret_xattrs = NULL;
 
-  file_input = (GInputStream*)gs_file_read_noatime (content_path, cancellable, error);
-  if (!file_input)
-    goto out;
-
-  if (fstat (g_file_descriptor_based_get_fd ((GFileDescriptorBased*)file_input), &stbuf) < 0)
+  if (out_input)
     {
-      ot_util_set_error_from_errno (error, errno);
-      goto out;
+      file_input = (GInputStream*)gs_file_read_noatime (content_path, cancellable, error);
+      if (!file_input)
+        goto out;
+      
+      if (fstat (g_file_descriptor_based_get_fd ((GFileDescriptorBased*)file_input), &stbuf) < 0)
+        {
+          ot_util_set_error_from_errno (error, errno);
+          goto out;
+        }
+
+      length = stbuf.st_size;
     }
+  else
+    {
+      GMappedFile *mmaped;
+      GBytes *bytes;
 
-  length = stbuf.st_size;
+      mmaped = gs_file_map_noatime (content_path, cancellable, error);
+      if (!mmaped)
+        goto out;
+      bytes = g_mapped_file_get_bytes (mmaped);
+      g_mapped_file_unref (mmaped);
+      mmaped = NULL;
+      file_input = g_memory_input_stream_new_from_bytes (bytes);
+      length = g_bytes_get_size (bytes);
+      g_bytes_unref (bytes);
+    }
 
   if (!ostree_content_stream_parse (compressed, file_input, length, trusted,
                                     out_input ? &ret_input : NULL,
                                     &ret_file_info, &ret_xattrs,
                                     cancellable, error))
     goto out;
-
+      
   ret = TRUE;
   ot_transfer_out_value (out_input, &ret_input);
   ot_transfer_out_value (out_file_info, &ret_file_info);